from django.shortcuts import render
from django.http import JsonResponse, FileResponse, HttpResponse
from demo.models import team_modelLast,team_model
from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser, FormParser
from demo.serializers import TeamUploadSerializers
from rest_framework.response import Response
from rest_framework import status
import datetime
from demo.models import TeamUploadLast
import json
import pandas as pd
import requests
from sklearn.metrics import roc_auc_score
from djangoProject import settings
import os
import pymysql


def show_my_team(request):
    try:
        if request.method == 'POST':
            user = json.loads(request.body)["user"]
            teams = team_modelLast.objects.filter(user=user).order_by("times")
            data = list(map(func2, teams))
            return JsonResponse({"code": 200, "data": data})
    except:
        return JsonResponse({"code": 500, "msg": "服务器出错！"})


def func2(tests):
    result = {
        "team_id": tests.team_id,
        "team_name": tests.team_name,
        "accuracy": round(tests.accuracy, 4),
        "times": tests.times,
        "track": "高职高专本科" if tests.track == 0 else "研究生",
        "team_num": tests.team_num,
        "update_time": tests.update_time
    }
    return result


def show_master_teams(request):
    try:
        if request.method == "POST":
            user = json.loads(request.body)['user']
            if team_modelLast.objects.filter(track=1).exists():
                teams = team_modelLast.objects.filter(track=1).order_by("-accuracy")[0]
                master_track = []
                all_times = len(team_modelLast.objects.filter(team_id=teams.team_id))
                data = {
                    "update_time": teams.update_time,
                    "accuracy": round(teams.accuracy, 4),
                    "track": "高职高专本科" if teams.track == 0 else "研究生",
                    "all_times": all_times,
                    "team_name": teams.team_name,
                    "team_id": teams.team_id,
                    "order": 1
                }
                master_track.append(data)
                if team_modelLast.objects.filter(track=1, user=user).exists():
                    my_teams = team_modelLast.objects.filter(user=user, track=1).order_by('-accuracy')[0]
                    # 先获取当前用户的精度

                    my_accuracy = team_modelLast.objects.filter(user=user, track=1).order_by('-accuracy')[0].accuracy
                    teams_ids = list(set(list(team_modelLast.objects.filter(track=1).values_list("team_id", flat=True))))

                    # 筛选出所有高于此精度的数据，取一下count就是当前用户的排名
                    teams_acc = list(map(func1, teams_ids))
                    teams_acc.sort()
                    order = teams_acc[::-1].index(my_accuracy) + 1
                    if order == 1:
                        my_data = {}
                    else:
                        my_all_times = len(team_modelLast.objects.filter(user=user, track=1))

                        my_data = {
                            "update_time": my_teams.update_time,
                            "accuracy": round(my_teams.accuracy, 4),
                            "track": "高职高专本科" if my_teams.track == 0 else "研究生",
                            "all_times": my_all_times,
                            "team_name": my_teams.team_name,
                            "team_id": my_teams.team_id,
                            "team_num": my_teams.team_num,
                            "order": order
                        }
                    master_track.append(my_data)
                result = {
                    "master_track": master_track,
                    "code": 200,
                    "msg": "数据加载成功"
                }
                return JsonResponse(result, charset='utf8')
            else:
                result = {
                    "master_track": [],
                    'msg': "暂无数据查看，请先提交文件",
                    'code': 201,
                }
                return JsonResponse(result, charset='utf8')
    except Exception as e:
        result = {
            'msg': '服务器错误',
            'code': 500
        }
        return JsonResponse(result, charset='utf8')


def show_bachelor_teams(request):
    try:
        if request.method == "POST":
            user = json.loads(request.body)['user']
            if team_modelLast.objects.filter(track=0).exists():
                teams = team_modelLast.objects.filter(track=0).order_by("-accuracy")[0]
                bachelor_track = []
                all_times = len(team_modelLast.objects.filter(team_id=teams.team_id))
                data = {
                    "update_time": teams.update_time,
                    "accuracy": round(teams.accuracy, 4),
                    "track": "高职高专本科" if teams.track == 0 else "研究生",
                    "all_times": all_times,
                    "team_name": teams.team_name,
                    "team_id": teams.team_id,
                    "order": 1
                }
                bachelor_track.append(data)
                if team_modelLast.objects.filter(track=0, user=user).exists():

                    # 先获取当前用户的精度
                    my_teams = team_modelLast.objects.filter(user=user,track=0).order_by('-accuracy')[0]
                    my_accuracy = team_modelLast.objects.filter(user=user,track=0).order_by('-accuracy')[0].accuracy
                    teams_ids = list(set(list(team_modelLast.objects.filter(track=0).values_list("team_id", flat=True))))

                    # 筛选出所有高于此精度的数据，取一下count就是当前用户的排名
                    teams_acc = list(map(func1, teams_ids))
                    teams_acc.sort()
                    order = teams_acc[::-1].index(my_accuracy) + 1
                    if order == 1:
                        my_data = {}
                    else:
                        my_all_times = len(team_modelLast.objects.filter(user=user, track=0))

                        my_data = {
                            "update_time": my_teams.update_time,
                            "accuracy": round(my_teams.accuracy, 4),
                            "track": "高职高专本科" if my_teams.track == 0 else "研究生",
                            "all_times": my_all_times,
                            "team_name": my_teams.team_name,
                            "team_id": my_teams.team_id,
                            "team_num": my_teams.team_num,
                            "order": order
                        }
                    bachelor_track.append(my_data)
                result = {
                    "bachelor_track": bachelor_track,
                    "code": 200,
                    "msg": "数据加载成功"
                }
                return JsonResponse(result, charset='utf8')
            else:
                result = {
                    "bachelor_track": [],
                    'msg': "暂无数据查看，请先提交文件",
                    'code': 201,
                }
                return JsonResponse(result, charset='utf8')
    except Exception as e:
        print(e)
        result = {
            'msg': '服务器错误',
            'code': 500
        }
        return JsonResponse(result, charset='utf8')


# 获取团队的最大模型精度值
def func1(teams_id):
    acc = team_modelLast.objects.filter(team_id=teams_id).order_by('-accuracy')[0].accuracy
    return acc


def grade():
    try:
        df = pd.concat([pd.read_excel(r"./grade/本科排名.xlsx"),pd.read_excel(r"./grade/研究生排名.xlsx")])
        list1 = df["团队id"].tolist()
        list2 = list(set(list(team_model.objects.filter(team_id__in=list1).values_list("user",flat=True))))
    except Exception as e:
        print('捕获到异常',e)
        return []
    return list2


class TeamUploadAPIView(APIView):
    parser_classes = (MultiPartParser, FormParser)

    def post(self, request):
        file_serializer = TeamUploadSerializers(data=request.data)
        print(request.data['uploader'])
        print("------------------------")
        print(list(map(str,grade())))
        if request.data['uploader'] in list(map(str,grade())):
            print("111111111111")
            pass
        else:
            print("22222222222222")
            return Response({'msg': '上传失败，非法账户,账号所属团队未进入决赛！', "code": 201}, status=status.HTTP_201_CREATED)
        if file_serializer.is_valid():
            day_of_upload_num = list(TeamUploadLast.objects.filter(uploader=file_serializer.validated_data["uploader"]).values_list("timestamp", flat=True))
            today = datetime.date.today()
            upload_num = cat_upload_num_today(day_of_upload_num, today)

            if upload_num >= 3:
                return Response({'msg': '上传失败，当日提交已超过3次！', "code": 201}, status=status.HTTP_201_CREATED)
            user = file_serializer.validated_data['uploader']
            db = pymysql.connect(host='43.139.129.126',
                                 user='root',
                                 password='Bigdata123',
                                 database='bigdata')

            cursor = db.cursor()

            sql = f"""
            SELECT  b.team_id, b.track, b.teams_name, b.teams_number
            from user_info a
            INNER JOIN team_information b ON a.id=b.user_index_id
            where a.user_name={user};"""

            cursor.execute(sql)
            # ----  数据库团队信息  ---
            data = cursor.fetchall()

            if data == ():
                return Response({'msg': '上传失败，非法账户,请使用参赛队长账号进行操作！', "code": 201}, status=status.HTTP_201_CREATED)

            team_id = data[0][0]
            track = data[0][1]
            team_name = data[0][2]
            teams_number = data[0][3]

            num = len(team_modelLast.objects.filter(user=user))
            try:
                if file_serializer.is_valid():
                    file_serializer.save()  # 保存上传的文件及相关信

                    groud_truth_path = os.path.join(r"./result/C_final_label.csv")
                    last_path = str(TeamUploadLast.objects.filter(uploader=user).last().file)
                    save_path = os.path.join(settings.MEDIA_ROOT, last_path)

                    try:
                        accuracy = cat_acc(save_path, groud_truth_path)
                    except Exception as e:
                        print(e)
                        dir_path = save_path.replace("C_final.csv", "")
                        os.remove(os.path.join(save_path))
                        os.rmdir(dir_path)

                        TeamUploadLast.objects.filter(uploader=file_serializer.validated_data['uploader']).last().delete()
                        return Response({'msg': '上传失败，文件内容格式有误，请检查列名或者数据维度是否匹配！', "code": 201}, status=status.HTTP_201_CREATED)
                    else:
                        team_modelLast(accuracy=accuracy, times=num + 1, team_id=team_id, track=track, team_name=team_name, team_num=teams_number, user=user).save()
                        return Response({'msg': '上传成功', "code": 200}, status=status.HTTP_200_OK)

                else:
                    return Response({'msg': '文件上传失败', "code": 500}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
            except Exception as e:
                print(e)
                return Response({'msg': '上传失败', "code": 500}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        else:
            return Response({'msg': '上传失败，字段有误', "code": 201}, status=status.HTTP_201_CREATED)


def cat_upload_num_today(day_of_upload_num, today):
    result = []
    for i in day_of_upload_num:
        if str(i)[:10] == str(today):
            result.append(i)
        else:
            pass
    return len(result)


# def cat_acc(save_path, groud_truth_path):
#     predict_path = os.path.join(save_path)
#     label = pd.read_csv(groud_truth_path, sep=',')
#     predict = pd.read_csv(predict_path, sep=',')
#     data = label.merge(predict, on='index', how='left')
#     accuracy = roc_auc_score(data['like'], data['predict'])
#     return accuracy

def cat_acc(predict_path, groud_truth_path):
    label = pd.read_csv(groud_truth_path, sep=',')

    predict = pd.read_csv(predict_path, sep=',')
    data = label.merge(predict, on='index', how='left')

    assert label.shape[0] == data.shape[0]

    positive = data.loc[data['like'] == 1]
    num_positive = positive.shape[0]
    negative = data.loc[data['like'] == 0]
    negative = negative.iloc[-num_positive:]

    data = pd.concat([positive, negative])

    score = roc_auc_score(data['like'], data['predict'])
    return score


def login(request):
    if request.method == 'POST':
        login_url = "http://43.139.129.126:8000/login/"
        data = json.loads(request.body)

        user = data['user']

        password = data['password']
        body = {
            "user": user,
            "password": password,
            "varify": "D2TA654KIO3M380-D.*@DKH23NC55611*"
        }
        try:
            resp = requests.post(login_url, json=body)
            if resp.status_code == 200:
                data = resp.json()
                return JsonResponse(data)
            else:
                return JsonResponse({"msg": "登陆失败", "code": 201})
        except:
            return JsonResponse({"msg": "登陆失败", "code": 201})